package com.zxd.interview.conrruentbook;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.IntStream;

/**
 * 竞态条件
 * 以List为例测试竞态条件问题
 *
 */
public class RaceConditionArrayListTest {

    /**
     * 测试的元素
     */
    private static final String ELEMENT_DATA = "binghe";

    private static List<String> list = Collections.synchronizedList(new ArrayList<>());

    static {
        IntStream.range(0, 10).forEach((i) -> {
            list.add(ELEMENT_DATA);
        });
    }
    /**
     * 遍历容器
     */
    private static void ergodicArrayList(){
        // 去除同步，则有可能
        synchronized (list){
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()){
                printElement(iterator.next());
            }
        }
    }

    private static void printElement(String str) {
        System.out.println("输出的元素信息====>>> " + str);
    }

    private static void removeElement(){
        list.remove(ELEMENT_DATA);
    }

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{ ergodicArrayList();}, "read-thread").start();
        new Thread(() -> {removeElement();}, "write-thread").start();
    }/*
    去除 synchronized 去除同步之后
    迭代器如果读线程读取和写线程
    输出的元素信息====>>> binghe
Exception in thread "read-thread" java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)
	at com.zxd.interview.conrruentbook.RaceConditionArrayListTest.ergodicArrayList(RaceConditionArrayListTest.java:36)
	at com.zxd.interview.conrruentbook.RaceConditionArrayListTest.lambda$main$1(RaceConditionArrayListTest.java:50)
	at java.base/java.lang.Thread.run(Thread.java:829)


    正确处理，加入同步机制
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    输出的元素信息====>>> binghe
    */

}
